package com.algorithms.absdatatypes;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

public final class BeanCreator
{

	/**
	 * Suppress constructor.
	 */
	private BeanCreator()
	{
	}

	/**
	 * Creates an object of the class name and supertype.
	 * 
	 * @param <T>
	 * @param className
	 * @param superType
	 * @return
	 * @throws ClassNotFoundException
	 */
	public static <T> T create(final String className, final Class<T> superType)
			throws Exception
	{
		final Class<? extends T> clazz = Class.forName(className).asSubclass(
				superType);
		return create(clazz);
	}

	/**
	 * Creates an object of the specified class using its public or private
	 * no-arg constructor.
	 * 
	 * @param <T>
	 * @param classToCreate
	 * @return
	 */
	public static <T> T create(final Class<T> classToCreate) throws Exception
	{
		final Constructor<T> constructor = classToCreate
				.getDeclaredConstructor();
		if (constructor == null)
		{
			throw new Exception("Could not create a new "
					+ "instance of the dest object: " + classToCreate
					+ ".  Could not find a no-arg constructor.");
		}

		// If private, make it accessible
		if (!constructor.isAccessible())
		{
			constructor.setAccessible(true);
		}
		return constructor.newInstance();
	}

	public static void main(String[] args) throws Exception
	{
		//
		try
		{
			
			List<TreeNode<String>>  list =new ArrayList<TreeNode<String>>();
			BeanCreator.create(list.getClass()).toString();
			//Class<?> abc =Class.forName("com.algorithms.absdatatypes.TreeNode");
			//Class<?> abc =Class.forName("java.util.ArrayList");
			System.out.println(list.hashCode());
			System.out.println(BeanCreator.create(list.getClass()).hashCode());
		}
		catch(Throwable x)
		{
			x.printStackTrace();
		}
	}
}
